RESTful API接口规范

MuYan2022-04-15规范规范

前言

为了前后端分工明确,对接流畅,确保可读性和扩展性以及高可用、一致性,特约定下述无状态 RESTful API 接口规范。

主要原则

RESTful API 统一约束客户端和服务器之间的接口。简化和分离系统架构,使每个模块独立。

  • 请求中使用 URI 定位资源
  • 用 HTTP Verbs[动词](GET、POST、PUT、PATCH、DELETE)描述操作(具体表现形式)
  • 数据传递(默认)采用:Content-Type: application/json; charset=utf-8
  • 单一职责原则:每个接口只负责一个职责,各个职责的接口改动,不影响其它接口
  • 接口隔离原则:用多个专门的接口,而不使用单一的总接口

RESTful 资源操作

RESTful 中根据操作资源的不同,使用不同的 http 方法。

  • 幂等性:对同一 REST 接口的多次访问,得到的资源状态是相同的;
  • 安全性:对该 REST 接口访问,不会使服务器端资源的状态发生改变。
http 方法资源操作幂等安全
GETSELECT
POSTINSERT
PUTUPDATE
PATCHUPDATE
DELETEDELETE

传统的 URL

GET /users/query/1 根据用户id查询用户数据
POST /users/save 新增用户
POST /users/update 修改用户信息
POST /users/delete 删除用户信息

RESTful 风格的 URL

GET /users/{id} 根据用户id查询用户数据
POST /users 新增用户
PUT /users 修改用户信息(客户端提供改变后的完整资源)
PATCH /users 修改用户信息(客户端提供改变的属性)
DELETE /users/{id} 删除用户信息

RESTful 设计准则

宾语必须是名词

宾语就是 API 的 URL,是 HTTP 动词作用的对象。它应该是名词,不能是动词。比如,/articles 这个 URL 就是正确的,而下面的 URL 不是名词,所以都是错误的。

 /getAllCars
 /createNewCar
 /deleteAllRedCars

小驼峰命名

宾语使用全小写名词表示,但有时一个名词无法完全描述清楚时,统一使用小驼峰命名

GET /companyContracts/1

复数 URL

既然 URL 是名词,那么应该使用复数,还是单数? 这没有统一的规定,但是常见的操作是读取一个集合,比如 GET /articles(读取所有文章),这里明显应该是复数。 为了统一起见,建议都使用复数 URL,比如 GET /articles/2 要好于 GET /article/2。

避免多级 URL

常见的情况是,资源需要多级分类,因此很容易写出多级的 URL,比如获取某个作者的某一类文章。

GET /authors/12/categories/2

这种 URL 不利于扩展,语义也不明确,往往要想一会,才能明白含义。 更好的做法是,除了第一级,其他级别都用查询字符串表达。

GET /authors/12?categories=2

下面是另一个例子,查询已发布的文章。你可能会设计成下面的 URL。

GET /articles/published

查询字符串的写法明显更好。

GET /articles?published=true

版本号放入 URL

若有多个 API 版本,应该将 API 的版本号放入 URI

GET /api/v2/authors/1

移动端接口

遵循最小化原则,业务完全相同使用同一个接口,不同则添加/mobile 体现 PC 端和移动端的对应关系

GET /authors/12
GET /mobile/authors/12

Swagger 注释

在 Swagger 中需包含详细注释说明,包括:

  • 接口描述
  • 请求数据类型(application/x-www-form-urlencoded、application/json 等)
  • 请求参数说明、数据类型、是否必须
  • 返回参数说明、数据类型

返回结果

API 返回结果应遵循以下格式与字段命名:

{
 "code":200, // 状态码以code命名(好多javascript框架并不会获取http状态码,所以包装到body中便于使用)
 "result": {   // 返回内容以result命名,多条记录使用JSON数组,单条记录使用JSON对象
  "id":null,   // 数据类型String,空时为null
  "name":"张三",
  "age":20 , // 数据类型Number, 空时为null,
  "imgUrls": ['地址1', '地址2'],  //数据类型Array, 空时为null
  "photoUrls": null
 },
 "message":"成功", // 成功或错误消息,以message命名
 "success": true // 是否成功:true或false
}

分页列表返回结果:

{
 "code":200, // 状态码以code命名(好多javascript框架并不会获取http状态码,所以包装到body中便于使用)
 "result": {
  "current": 1, // 当前页数以current命名
  "pages": 2, // 总页数以pages命名
  "records": [{...}, {...}], // 返回列表以records命名,使用JSON数组
  "size": 10, // 每页条数以size命名
  "total": 12 // 总条数以total命名
 },
 "message":"成功", // 成功或错误消息,以message命名
 "success": true // 是否成功:true或false
}

状态码

服务器向用户返回的状态码和提示信息,常见的有以下一些(方括号中是该状态码对应的 HTTP 动词)

- 200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。
- 201 CREATED - [POST/PUT]:用户新建或修改数据成功。
- 202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)
- 204 NO CONTENT - [DELETE]:用户删除数据成功。
- 400 INVALID REQUEST - [POST/PUT]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。
- 401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。
- 403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。
- 404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。
- 406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。
- 410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。
- 422 Unprocesable entity - [POST/PUT] 当创建一个对象时,发生一个验证错误。
- 500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。
上次更新 2026/6/23 11:49:15
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.8